# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
 -------------------------------------------------
    File Name:     __init__.py.py
    Description:   allure 服务管理
 -------------------------------------------------
 """
import logging
import os
import subprocess
import socket

# from apitesting.common.util.logger import log as log
from apitesting.config import paths

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class ReportManager:

    @staticmethod
    def stop_allure_server():
        """
        停止 Allure 服务
        """
        pid = PIDManager.get_saved_pid()
        if pid:
            try:
                os.kill(pid, 9)
                logger.info(f"✅ 停止 Allure 服务 (PID: {pid}) 成功")
                os.remove(PIDManager.PID_FILE)
            except Exception as e:
                logger.warning(f"⚠️ 无法停止服务 (PID: {pid}): {e}")
        else:
            logger.warning("⚠️ 未找到正在运行的 Allure 服务")

    @staticmethod
    def start_allure_server(port: int = 50321):
        """
        启动 Allure 服务并保存 PID
        """
        try:
            logger.info(f"🌐 正在启动 Allure 服务 (端口 {port})...")
            server_command = [
                "allure", "open",
                "--port", str(port),
                paths.ALLURE_REPORT_DIR.as_posix(),
                "--no-browser",
            ]
            # 启动守护进程
            process = subprocess.Popen(server_command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
            PIDManager.save_pid(process.pid)

            report_url = f"http://localhost:{port}/"
            logger.info(f"✅ Allure 服务已启动，访问以下地址查看报告: {report_url}")
            logger.info(f"\n👉 打开报告地址: {report_url}")
        except Exception as e:
            logger.error(f"❌ 启动 Allure 服务失败1")
            raise Exception("启动 Allure 服务失败2") from e
            # raise e from e


class PIDManager:
    """
    用于检查和管理进程 PID 的类
    """

    PID_FILE = "./allure_server.pid"

    @staticmethod
    def save_pid(pid: int):
        """
        保存 PID 到文件
        """
        with open(PIDManager.PID_FILE, 'w') as f:
            f.write(str(pid))
        logger.info(f"✅ 保存 Allure 服务的 PID: {pid}")

    @staticmethod
    def get_saved_pid() -> int | None:
        """
        获取保存的 PID
        """
        if os.path.exists(PIDManager.PID_FILE):
            with open(PIDManager.PID_FILE, 'r') as f:
                return int(f.read().strip())
        return None


class PortManager:
    """
    用于检查和管理端口状态的类
    """

    @staticmethod
    def is_port_in_use(port: int) -> bool:
        """
        检查端口是否被占用
        """
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            try:
                s.bind(('localhost', port))
                s.close()
                return False
            except OSError:
                return True

    @staticmethod
    def kill_process_on_port(port: int):
        """
        杀死占用指定端口的进程
        """
        try:
            result = subprocess.run(
                f"lsof -i:{port} | grep LISTEN | awk '{{print $2}}' | xargs kill -9",
                shell=True,
                check=False,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            if result.returncode == 0:
                logger.info(f"✅ 已清理占用端口 {port} 的进程")
            else:
                logger.warning(f"⚠️ 清理端口 {port} 失败，可能无占用或权限不足")
        except Exception as e:
            logger.error(f"❌ 无法清理端口 {port}: {e}")


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description="Allure 报告服务管理")
    parser.add_argument("--start", action="store_true", help="启动 Allure 服务")
    parser.add_argument("--stop", action="store_true", help="停止 Allure 服务")
    parser.add_argument("--port", type=int, default=50321, help="Allure 服务端口号")

    args = parser.parse_args()

    if args.stop:
        ReportManager.stop_allure_server()
    elif args.start:
        ReportManager.start_allure_server(port=args.port)
    else:
        parser.print_help()
